package com.infolab.aims.web;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.infolab.aims.GlobalConstant;
import com.infolab.aims.common.AbstractController;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.bean.SearchResult;
import com.infolab.aims.common.exception.ResourceNotFoundException;
import com.infolab.aims.domain.Section;
import com.infolab.aims.domain.SystemAccessRight;
import com.infolab.aims.domain.SystemRole;
import com.infolab.aims.service.intf.RoleService;
import com.infolab.aims.web.form.SystemRoleForm;


@Controller
@RequestMapping("/role")
@SessionAttributes(value=RoleController.SESSION_SEARCH_CRITERIA)
public class RoleController extends AbstractController {
	
	public static final String SESSION_SEARCH_CRITERIA ="searchCriteria";
	public static final String CONTEXT_PATH ="/role";
	public static final String JSP_MAIN_FORM="roleForm";
	public static final String JSP_MAIN_SEARCH="roleSearch";

	@Autowired
	RoleService roleService;
	
	@RequestMapping(value="create", method = RequestMethod.GET)
	public String createRole(Model model) {
		SystemRoleForm systemRoleForm = new SystemRoleForm();
		model.addAttribute(systemRoleForm);
		return JSP_MAIN_FORM;
	}
	
	@RequestMapping(value="create",method=RequestMethod.POST)
	public String saveRole(@ModelAttribute SystemRoleForm systemRoleForm, BindingResult result,Model model,HttpServletRequest request) {
		
		SystemRole systemRole = systemRoleForm.getSystemRole();
		
		String []accessRightId = request.getParameterValues("selSystemAccessRight");
		List<SystemAccessRight> systemAccessRights = new ArrayList<SystemAccessRight>();
		Map<String,String> accessRightMap = (Map<String, String>) request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_ACCESS_RIGHT_MAP);
		if(accessRightId!=null)
		{
			for(int i=0;i<accessRightId.length;i++)
			{
				SystemAccessRight systemAccessRight = new SystemAccessRight();
				systemAccessRight.setAccessRightId(accessRightId[i]);
				systemAccessRight.setAccessRightName(accessRightMap.get(accessRightId[i]));
				systemAccessRights.add(systemAccessRight);
			}
		}
		systemRole.setSystemAccessRights(systemAccessRights);
		
		if (validateRole(systemRoleForm,result)) {	
			return JSP_MAIN_FORM;
		}
		
		systemRole.setCreatedBy(getCurrentUserName(request));
		
		prepareAuditObject(systemRole, request);
		roleService.createRole(systemRole);
		
		refreshGlobalRole(request);
		
		setSuccessMessage(getMessageResources("success.create","role " + systemRole.getRoleName()));
		
		return "redirect:"+CONTEXT_PATH+"/update/" + systemRole.getSystemRoleId();
	}
	
	@RequestMapping(value="update/{id}",method=RequestMethod.POST)
	public String updateRole(@PathVariable Integer id,@ModelAttribute SystemRoleForm systemRoleForm, BindingResult result,Model model,HttpServletRequest request) {
		
		SystemRole systemRole = systemRoleForm.getSystemRole();
		
		String []accessRightId = request.getParameterValues("selSystemAccessRight");
		List<SystemAccessRight> systemAccessRights = new ArrayList<SystemAccessRight>();
		Map<String,String> accessRightMap = (Map<String, String>) request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_ACCESS_RIGHT_MAP);
		if(accessRightId!=null)
		{
			for(int i=0;i<accessRightId.length;i++)
			{
				SystemAccessRight systemAccessRight = new SystemAccessRight();
				systemAccessRight.setAccessRightId(accessRightId[i]);
				systemAccessRight.setAccessRightName(accessRightMap.get(accessRightId[i]));
				systemAccessRights.add(systemAccessRight);
			}
		}
		systemRole.setSystemAccessRights(systemAccessRights);
		
		if (validateRole(systemRoleForm,result)) {
			return JSP_MAIN_FORM;
		}
		
		systemRole.setModifiedBy(getCurrentUserName(request));
		
		prepareAuditObject(systemRole, request);
		roleService.updateRole(systemRole);
		
		refreshGlobalRole(request);
		
		setSuccessMessage(getMessageResources("success.update","role " + systemRole.getRoleName()));
		
		return "redirect:"+CONTEXT_PATH+"/update/" + systemRole.getSystemRoleId();	
		
	}

	@RequestMapping(value={"update/{id}","detail/{id}"}, method = RequestMethod.GET)
	public String detailRole(@PathVariable Integer id,Model model,HttpServletRequest request) {
		
		SystemRole systemRole = roleService.getRole(id);
		if(systemRole==null) {
			throw new ResourceNotFoundException("Role " + id);
		}
		
		String url = request.getServletPath();
		
		SystemRoleForm systemRoleForm = new SystemRoleForm();
		systemRoleForm.setSystemRole(systemRole);
	
		
		if(StringUtils.contains(url, GlobalConstant.FORM_MODE_UPDATE))
		{
			model.addAttribute(systemRoleForm);
			return JSP_MAIN_FORM;
		}

		return JSP_MAIN_FORM;
	}
	
	
	
	@ModelAttribute(RoleController.SESSION_SEARCH_CRITERIA)
	public SearchCriteria getRoleSearchCriteria()
	{
		return new SearchCriteria();
	}
	

	@RequestMapping(value="search")
	public String searchRole(@ModelAttribute(RoleController.SESSION_SEARCH_CRITERIA) SearchCriteria searchCriteria,@ModelAttribute("currentSearchCriteria") SearchCriteria currentSearchCriteria,Model model) {
		
		if(currentSearchCriteria.getCurPage()!=null)
			searchCriteria.setCurPage(currentSearchCriteria.getCurPage());
		
		searchCriteria.addSearchCriteria("active", true);
		SearchResult searchResult = roleService.searchRole(searchCriteria);
		model.addAttribute(searchResult);
		
		return JSP_MAIN_SEARCH;
	}
	
	@RequestMapping(value={"delete/{id}"}, method = RequestMethod.GET)
	public String deleteRole(@PathVariable Integer id,Model model,HttpServletRequest request) {
		
		SystemRole systemRole = roleService.getRole(id);
		if(systemRole==null) {
			throw new ResourceNotFoundException("Role " + id);
		}
		prepareAuditObject(systemRole, request);
		roleService.deleteRole(systemRole);
		
		refreshGlobalRole(request);
		
		return "redirect:"+CONTEXT_PATH+"/search";
	}
	
	private boolean validateRole(SystemRoleForm systemRoleForm,BindingResult result)
	{	
		if(systemRoleForm.getSystemRole().getSection().getSectionId()==null)
			systemRoleForm.getSystemRole().setSection(null);
		
		validator.validate(systemRoleForm, result);
		
		if(systemRoleForm.getSelSystemAccessRight()==null || systemRoleForm.getSelSystemAccessRight().size()==0)
			result.rejectValue("selSystemAccessRight", "error.empty", new String[]{"Access Right"}, "");
		
		return result.hasErrors();
	}
	

	private void prepareAuditObject(SystemRole systemRole, HttpServletRequest request){
		/* audit start */
		Section sec = findSection(request, systemRole.getSection().getSectionId());
		systemRole.setSection(sec);		
		
		if(systemRole.getSystemAccessRights()!=null && CollectionUtils.isNotEmpty(systemRole.getSystemAccessRights())){
		List<SystemAccessRight> list = systemRole.getSystemAccessRights();
			if(CollectionUtils.isNotEmpty(list)){
	
				for(SystemAccessRight detail : list){
					if(detail.getAccessRightId() != null){
						String accessRightId = detail.getAccessRightId();
						SystemAccessRight tmp  = findAccessRights(request, accessRightId);
						detail.setAccessRightName(tmp.getAccessRightName());
					}
				}
			}
		}
		
		/* audit end */	
	}

}
